/**
 * 百度语音合成
 * 技术文档：https://ai.baidu.com/ai-doc/SPEECH/pk4nlz7vk
 * 管理控制台：https://console.bce.baidu.com/ai/?_=1632206293784#/ai/speech/overview/index
 */
import { speech as AipSpeechClient } from 'baidu-aip-sdk';
import { BAIDU_AI_APP_ID, BAIDU_AI_SECRET_KEY, BAIDU_AI_APP_KEY } from '../config';
import uuid from 'uuid';
import Queue from 'p-queue';
import { Duplex } from 'stream';
import { getAudioDurationInSeconds } from 'get-audio-duration';
import mp3Duration from 'mp3-duration';
import { qiniuUpload } from './qiniuUpload';

const MAX_TEXT_LENGTH = 200;

export default async function voiceTransMp3(data = {}) {
  const result = [];
  const { content = '', split = false } = data;
  const client = new AipSpeechClient(BAIDU_AI_APP_ID, BAIDU_AI_APP_KEY, BAIDU_AI_SECRET_KEY);

  if (!content) return result;

  if (split) {
    return new Promise((tresolve, treject) => {
      try {
        const paramNum = Math.ceil(content.length / MAX_TEXT_LENGTH);
        const queue = new Queue({ concurrency: 3, autoStart: false });
        const transPromiseArr = [];
        for (let i = 0; i < paramNum; i++) {
          const endPoint = content.length > MAX_TEXT_LENGTH * (i + 1) ? MAX_TEXT_LENGTH * (i + 1) : content.length;
          const subContent = content.substring(MAX_TEXT_LENGTH * i, endPoint);
          const options = { spd: 5, per: 4 }; // 语速中等，语音度丫丫
          queue.add(() => {
            return new Promise((resolve, reject) => {
              client.text2audio(subContent, options).then(
                function (result) {
                  if (!result || !result.data) reject(new Error('百度语音合成失败'));
                  // 计算时长
                  mp3Duration(result.data, function (err, duration) {
                    if (err) return reject(err);
                    // 七牛上传
                    qiniuUpload(result.data, 'mbook/voice/' + uuid.v1() + '.mp3')
                      .then(res => {
                        transPromiseArr.push({ key: i, url: res, duration });
                        resolve(res);
                      })
                      .catch(err => {
                        reject(err);
                      });
                  });
                },
                function (err) {
                  treject(err);
                }
              );
            });
          });
        }

        queue.start();
        queue.onIdle().then(() => {
          tresolve(
            transPromiseArr
              .sort((arr1, arr2) => {
                return arr1.key - arr2.key;
              })
              .map(item => {
                return { url: item.url, time: item.duration };
              })
          );
        });
      } catch (err) {
        console.log('百度语音合成失败', err);
        treject(err);
      }
    });
  } else {
    return new Promise((resolve, reject) => {
      client.text2audio(content).then(
        function (result) {
          if (!result || !result.data) reject(new Error('百度语音合成失败'));
          // 计算时长
          const readStream = new Duplex();
          readStream.push(result.data);
          readStream.push(null);
          getAudioDurationInSeconds(readStream)
            .then(duration => {
              // 七牛上传
              qiniuUpload(result.data, 'mbook/share/' + uuid.v1() + '.mp3')
                .then(res => {
                  resolve({ url: res, time: duration });
                })
                .catch(() => {
                  reject(new Error('七牛上传错误'));
                });
            })
            .catch(() => {
              reject(new Error('获取时长失败'));
            });
        },
        function () {
          reject(new Error('百度语音合成出现网络错误'));
        }
      );
    });
  }
}
